// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
 * Description: when uncorrected patrol scrub error happens, isolate
 * page but do not kill related processes
 * Author: Lv Ying
 * Create: 2019-06-18
 */

#include <linux/printk.h>
#include <linux/mm.h>
#include <linux/cper.h>
#include <acpi/ghes.h>

#include "euleros_uc_ps_mem_isolate.h"

#define UC_PATROL_SCRUB_ERROR 14
#define GHES_PFX        "GHES: "

int uc_ps_mem_isolate;

static int  __init uc_ps_mem_isolate_setup(char *s)
{
	pr_warn("RAS: Enable uc_ps_mem_isolate kernel option\n");
	uc_ps_mem_isolate = 1;
	return 0;
}
early_param("uc_ps_mem_isolate", uc_ps_mem_isolate_setup);

void isolate_uncorrected_patrol_scrub_error(
		const struct cper_sec_mem_err *mem_err,
		int *flags,
		int sec_sev)
{
	/* if error type is uncorrected patrol scrub error, this error should
	 * be isolated but do not kill related processes */
	if (uc_ps_mem_isolate && sec_sev == GHES_SEV_CORRECTED &&
			(mem_err->validation_bits & CPER_MEM_VALID_ERROR_TYPE)
			&& mem_err->error_type == UC_PATROL_SCRUB_ERROR) {
#ifdef CONFIG_EULEROS_RAS_MEM_OFFLINE_NOTIFY
		*flags = MF_SOFT_OFFLINE | MF_SRAO;
		pr_warn_ratelimited(FW_WARN GHES_PFX
			"RAS: In ghes_handle_memory_failure, the error is uncorrected patrol scrub error, physical address is %#llx",
			mem_err->physical_addr);
#else
		*flags = MF_SOFT_OFFLINE;
#endif
	}
}
